package com.version.manager.service;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.version.manager.annotaion.OrderColumn;
import com.version.manager.annotaion.StatusColumn;
import com.version.manager.constant.OrderType;
import com.version.manager.constant.QueryType;
import com.version.manager.model.Msg;
import com.version.manager.model.TableResultResponse;
import com.version.manager.util.EntityUtil;
import com.version.manager.util.QueryParam;
import com.version.manager.util.ReflectionUtil;
import javafx.scene.control.Tab;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.swing.table.TableColumn;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.UUID;

public abstract class BaseService<M extends Mapper<T>,T> {

    private Logger log= LoggerFactory.getLogger(BaseService.class);
    @Autowired
    protected M mapper;
    @Autowired
    private ReflectionUtil reflectionUtil;
    public void setMapper(M mapper){
        this.mapper=mapper;
    }
    public T selectOne(T t){
        return mapper.selectOne(t);
    }
    public T selectById(Object id){
        return mapper.selectByPrimaryKey(id);
    }
    public List<T> selectList(T t){

        return mapper.select(t);
    }
    public List<T> selectList(QueryParam queryParam){
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        Field[] fields=clazz.getFields();
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();
        if(queryParam.entrySet().size()>0) {
            for (Map.Entry<String, Object> entry : queryParam.entrySet()) {
                //获取查询方式，默认为精确查询
                QueryType queryType=reflectionUtil.getQueryType(fields,entry.getKey());
                if(queryType==QueryType.Exactly){
                    criteria.andEqualTo(entry.getKey(),entry.getValue());
                }else{
                    criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
                }
            }
        }
        //有状态列，获取状态列为显示的数据
        StatusColumn statusColumn= clazz.getAnnotation(StatusColumn.class);
        if(statusColumn!=null){
            criteria.andEqualTo(statusColumn.name(),statusColumn.show());
        }

        //有排序列的读取排序列
        OrderColumn orderColumn=clazz.getAnnotation(OrderColumn.class);
        if(orderColumn!=null) {
            if(orderColumn.orderType()==OrderType.ASC){
                example.orderBy(orderColumn.name()).asc();
            }else{
                example.orderBy(orderColumn.name()).desc();
            }

        }

        List<T> list = mapper.selectByExample(example);
        return list;
    }




    public List<T> selectListAll(){
        return mapper.selectAll();
    }
    public String createId(){
        return UUID.randomUUID().toString().replace("-","");
    }

    public Msg delete(T data,boolean realDelete) throws Exception{
        try{
            if(!realDelete){
                Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
                StatusColumn statusColumn= clazz.getAnnotation(StatusColumn.class);
                if(statusColumn!=null){

                    //读取状态列的数据库字段名
                    Field[] fields=clazz.getDeclaredFields();

                    for(Field f:fields){
                        if(f.getName().equals(statusColumn.name())){
                            ReflectionUtil.setFieldValue(data,f.getName(),0);
                            break;
                        }
                    }
                    int count= mapper.updateByPrimaryKeySelective(data);
                    if(count>0){
                        return Msg.success();
                    }
                    return Msg.fail().addMessage("删除失败");

                }else{
                    throw new Exception("没有状态列");
                }
            }else {
                int count= mapper.deleteByPrimaryKey(data);
                if(count>0){
                    return Msg.success();
                }
                return Msg.fail().addMessage("删除失败");
            }
        }catch (Exception ex){
            log.error("delete:"+ex.getMessage());
            return Msg.fail().addMessage("删除失败");
        }


    }


    public Msg saveOrUpdate(T data) throws Exception {
        try{

            Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
            Field[] fields=clazz.getDeclaredFields();
            Field priField=null;
            boolean hasId=false;
            String pid=null;
            for(Field f:fields){
                Id id= f.getAnnotation(Id.class);
                if(id!=null){
                    hasId=true;
                    priField=f;
                    break;
                }
            }
            if(!hasId){
                return Msg.fail().addMessage("未设置主键字段");
            }
            Object idValue= ReflectionUtil.getFieldValue(data,priField.getName());
            //主键为空，则为插入
            if(idValue==null||StringUtils.isEmpty(idValue.toString())){
                //主键为字符串，则设置主键为uuid
                if(priField.getType()==String.class){
                    pid=createId();
                    ReflectionUtil.setFieldValue(data,priField.getName(),pid);
                }
                EntityUtil.setCreateInfo(data);
                mapper.insert(data);
            }else{
                //主键不空，则更新
                EntityUtil.setUpdatedInfo(data);
                mapper.updateByPrimaryKey(data);
            }
            return Msg.success().addMessage("保存成功").addData(pid);
        }catch (Exception ex){
            log.error("saveOrUpdate:"+ex.getMessage());
            return Msg.fail().addMessage(ex.getMessage());
        }

    }

    public List<T> getAllList(){
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();
        //有状态列，获取状态列为显示的数据
        StatusColumn statusColumn= clazz.getAnnotation(StatusColumn.class);
        if(statusColumn!=null){
            criteria.andEqualTo(statusColumn.name(),statusColumn.show());
        }

        //有排序列的读取排序列
        OrderColumn orderColumn=clazz.getAnnotation(OrderColumn.class);
        if(orderColumn!=null) {
            if(orderColumn.orderType()==OrderType.ASC){
                example.orderBy(orderColumn.name()).asc();
            }else{
                example.orderBy(orderColumn.name()).desc();
            }

        }
        List<T> list = mapper.selectByExample(example);
        return list;

    }

    /**
     * 查询数据
     * @param queryParam
     * @return
     */
    public TableResultResponse<T> selectByQuery(QueryParam queryParam)  {
        Class<T> clazz = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        Field[] fields=clazz.getFields();
        Example example = new Example(clazz);
        Example.Criteria criteria = example.createCriteria();
        if(queryParam.entrySet().size()>0) {
            for (Map.Entry<String, Object> entry : queryParam.entrySet()) {
                //获取查询方式，默认为精确查询
                QueryType queryType=reflectionUtil.getQueryType(fields,entry.getKey());
                if(queryType==QueryType.Exactly){
                    criteria.andEqualTo(entry.getKey(),entry.getValue());
                }else{
                    criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
                }
            }
        }
        //有状态列，获取状态列为显示的数据
        StatusColumn statusColumn= clazz.getAnnotation(StatusColumn.class);
        if(statusColumn!=null){
            criteria.andEqualTo(statusColumn.name(),statusColumn.show());
        }

        //有排序列的读取排序列
        OrderColumn orderColumn=clazz.getAnnotation(OrderColumn.class);
        if(orderColumn!=null) {
            if(orderColumn.orderType()==OrderType.ASC){
                example.orderBy(orderColumn.name()).asc();
            }else{
                example.orderBy(orderColumn.name()).desc();
            }

        }

        Page<Object> result = PageHelper.startPage(queryParam.getPage(), queryParam.getLimit());
        List<T> list = mapper.selectByExample(example);
        return new TableResultResponse<T>(result.getTotal(), list);
    }



}
